/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/cat.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../msg_aio/head.h"
#include "../config/head.h"
#include "../impl/head.h"
#include "../msg/head.h"
#include "net_udp.h"

namespace cat
{

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    net_udp::net_udp()
    {
    }

    net_udp::~net_udp()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // proc

    int net_udp::proc( xos::i_msg *& pMsg )
    {
        int ret = 1;

        int nMsg = pMsg->get_int( 0, 0 );

        switch( nMsg )
		{
        case NET_UDP_NEED_RELEASE:
            {
                on_need_release( pMsg );
            }
            break;
		case NET_UDP_NEED_CLOSE:
			{
                on_need_close( pMsg );
			}
			break;
        case NET_UDP_DATA_ERR:
            {
                on_data_err( pMsg );
            }
            break;
        case NET_UDP_INIT:
            {
                on_init( pMsg );
            }
            break;
        case NET_UDP_RECV:
            {
                on_recv( pMsg );
            }
            break;
        case NET_UDP_SEND:
            {
                on_send( pMsg );
            }
            break;
        case NET_UDP_SHUTDOWN:
            {
                on_shutdown( pMsg );
            }
            break;
        case NET_UDP_CLOSE:
            {
				on_close( pMsg );
            }
            break;
        default:
            {
                ret = 0;
            }
            break;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

	int net_udp::on_need_release( xos::i_msg *& pMsg )
	{
		int ret = 0;
        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );
        pConnect->helper_release();
		return ret;
	}

    int net_udp::on_need_close( xos::i_msg *& pMsg )
    {
        int ret = 0;

        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );

        if( 0 == ret )
        {
            aio_udp obj;
            ret = obj.post_close( pConnect, 0, 0 );
        }

        return ret;
    }

    int net_udp::on_data_err( xos::i_msg *& pMsg )
    {
        int ret = 0;

        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );

        if( 0 == ret )
        {
            aio_udp obj;
            ret = obj.post_close( pConnect, 1, 0 );
            pConnect->un_lock_server();
        }

        return ret;
    }

    // 
    // m_bData[0] : true or false for result
    // 
    // m_nData[0] : cmd type
    // 
    // m_nData[1] : local port
    // m_szStr[1] : local ip
    // 
    // m_lpData[0] : UserKey
    // m_lpData[1] : AioKey
    // 
    int net_udp::on_init( xos::i_msg *& pMsg )
    {
        int ret = 0;

        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );
        tcp * pTcp = pConnect->m_pTcp;
        bool bRet = pMsg->get_bool( 0, 0 );

        if( bRet )
        {
            msg::notify_main_main( pMsg, MAIN_STARTED, false );
        }
        else
        {
            tcp::term( pTcp );
        }

        return ret;
    }

    // 
    // m_bData[0] : true or false for opt result
    // 
    // m_nData[0] : cmd type
    // 
    // m_nData[1] : recv len
    // m_lpBuf[0] : recv buf
    // 
    // m_lpData[0] : UserKey
    // m_lpData[1] : AioKey
    // 
    int net_udp::on_recv( xos::i_msg *& pMsg )
    {
        int ret = 0;

        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );
        xos::i_buf * pBuf = pMsg->get_buf( 0, 0 );
        bool bRet = pMsg->get_bool( 0, 0 );
        task * pTask = pConnect->m_pTask;

        if( ( 0 == ret ) && !bRet )
        {
            ret = 1;
        }

        if( 0 == ret )
        {
            pMsg->set_void( 0, pTask );
            pBuf = 0;
        }

        if( 0 == ret )
        {
            msg::notify_package( pMsg, PACKET_UDP_UN_ENCRYPT, false );
            ret = 1;
        }

        xos_stl::release_interface( pBuf );

        return ret;
    }

    // 
    // m_bData[0] : true or false for opt result
    // 
    // m_nData[0] : cmd type
    // 
    // m_nData[1] : send bytes
    // m_lpBuf[0] : send buf
    // 
    // m_lpData[0] : UserKey
    // m_lpData[1] : AioKey
    // 
    int net_udp::on_send( xos::i_msg *& pMsg )
    {
        int ret = 0;

        connection * pConnect = (connection *)pMsg->get_void( 0, 0 );
        xos::i_buf * pBuf = pMsg->get_buf( 0, 0 );

        if( ( 0 == ret ) && ( pConnect->m_pCloseAfterSend == pBuf ) )
        {
            pConnect->net_timeout_ms = config::get()->net_timeout_ms - 2 * config::get()->heart_check_interval_ms;
            pConnect->m_pCloseAfterSend = ( xos::i_buf* )1;
            ret = 1;
        }

        if( ( 0 == ret ) && ( pConnect->m_pQuitAfterSend == pBuf ) )
        {
            pConnect->net_timeout_ms = config::get()->net_timeout_ms - 2 * config::get()->heart_check_interval_ms;
            pConnect->m_pQuitAfterSend = ( xos::i_buf* )1;
            ret = 1;
        }

        xos_stl::release_interface( pBuf );

        return ret;
    }

    int net_udp::on_shutdown( xos::i_msg *& pMsg )
    {
        int ret = 0;

        //connection * pConnect = (connection *)pMsg->get_void( 0, 0 );
        //tcp * pTcp = pConnect->m_pTcp;
        //bool bRet = pMsg->get_bool( 0, 0 );

        if( 0 == ret )
        {
        }

        return ret;
    }

	int net_udp::on_close( xos::i_msg *& pMsg )
	{
		int ret = 0;

		connection * pConnect = ( connection* )pMsg->get_void( 0, 0 );
        task * pTask = pConnect->m_pTask;

        pMsg->set_void( 0, pTask );
        pConnect->set_closed();

        msg::notify_package( pMsg, PACKET_UDP_UN_ENCRYPT_FLUSH, false );

		return ret;
	}

} // cat
